package cn.silver.module.system.bean;

import cn.silver.framework.core.constant.Constants;
import cn.silver.framework.core.constant.UserConstants;
import cn.silver.framework.core.utils.StringUtils;
import cn.silver.framework.mybatis.bean.TreeBean;
import cn.silver.framework.mybatis.domain.TreeEntity;
import cn.silver.module.system.domain.SysMenu;
import cn.silver.module.system.enums.MenuTypeEnums;
import io.github.linpeilie.annotations.AutoMapper;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

import java.io.Serial;
import java.io.Serializable;


/**
 * 菜单信息对象 MenuModel
 *
 * @author Silver Zhou
 */
@Data
@NoArgsConstructor
@AutoMapper(target = SysMenu.class)
@EqualsAndHashCode(callSuper = true)
@Schema(name = "MenuModel", title = "菜单信息对象")
public class MenuBean extends TreeBean<MenuBean> implements Serializable {

    @Serial
    private static final long serialVersionUID = 1L;

    /**
     * 菜单类型（M目录 C菜单 F按钮）
     */
    @Schema(title = "菜单类型")
    private String type;

    /**
     * 菜单图标
     */
    @Schema(title = "菜单图标")
    private String icon;

    /**
     * 路由地址
     */
    @Schema(title = "路由地址")
    private String url;
    /**
     * 路由参数
     */
    @Schema(title = "路由参数")
    private String param;

    /**
     * 组件路径
     */
    @Schema(title = "组件名称")
    private String component;

    /**
     * 组件路径
     */
    @Schema(title = "组件路径")
    private String path;

    /**
     * 显示状态（0显示 1隐藏）
     */
    @Schema(title = "显示状态")
    private Boolean visible;
    /**
     * 是否为外链（0是 1否）
     */
    @Schema(title = "是否为外链")
    private Boolean frame;
    /**
     * 是否缓存（0缓存 1不缓存）
     */
    @Schema(title = "是否缓存")
    private Boolean cache;

    /**
     * 内链域名特殊字符替换
     */
    public static String innerLinkReplaceEach(String path) {
        return StringUtils.replaceEach(path, new String[]{Constants.HTTP, Constants.HTTPS, Constants.WWW, "."},
                new String[]{"", "", "", "/"});
    }

    /**
     * 获取路由名称
     */
    public String getRouteName() {
        String routerName;
        // 非外链并且是一级目录（类型为目录）
        if (isMenuFrame()) {
            routerName = StringUtils.EMPTY;
        } else {
            routerName = this.component;
        }
        return routerName;
    }

    /**
     * 获取路由地址
     */
    public String getRouterPath() {
        String routerPath = this.url;
        // 内链打开外网方式
        if (!TreeEntity.ROOT_NODE.equalsIgnoreCase(this.getPid()) && isInnerLink()) {
            routerPath = innerLinkReplaceEach(routerPath);
        }
        if (TreeEntity.ROOT_NODE.equalsIgnoreCase(this.getPid()) && MenuTypeEnums.MENU_GROUP.getCode().equals(getType()) && !getFrame()) {
            // 非外链并且是一级目录（类型为目录）
            routerPath = "/" + this.url;
        } else if (isMenuFrame()) {
            // 非外链并且是一级目录（类型为菜单）
            routerPath = "/";
        }
        return routerPath;
    }

    /**
     * 获取组件信息
     */
    public String getComponentInfo() {
        String component = UserConstants.LAYOUT;
        if (StringUtils.isNotEmpty(this.path) && !isMenuFrame()) {
            component = this.path;
        } else if (StringUtils.isEmpty(this.path) && !TreeEntity.ROOT_NODE.equalsIgnoreCase(this.getPid()) && isInnerLink()) {
            component = UserConstants.INNER_LINK;
        } else if (StringUtils.isEmpty(this.path) && isParentView()) {
            component = UserConstants.PARENT_VIEW;
        }
        return component;
    }

    /**
     * 是否为菜单内部跳转
     */
    public boolean isMenuFrame() {
        return TreeEntity.ROOT_NODE.equalsIgnoreCase(this.getPid()) && UserConstants.TYPE_MENU.equals(this.type) && !this.frame;
    }

    /**
     * 是否为内链组件
     */
    public boolean isInnerLink() {
        return !this.frame && StringUtils.ishttp(path);
    }

    /**
     * 是否为parent_view组件
     */
    public boolean isParentView() {
        return !TreeEntity.ROOT_NODE.equalsIgnoreCase(this.getPid()) && MenuTypeEnums.MENU_GROUP.getCode().equals(this.type);
    }
}
